<?php

// Facebook Data Updater
// Updates data in DB by retrieving data from Facebook Platform
// This script is to be executed periodically via Cron (Unix) or Task Scheduler (Windows).
require_once 'inc/common.php';

// Get the array of users that require updating of data
$ufbid = isset($_GET['u']) ? $_GET['u'] : 0;
$users = $db->q('
	SELECT
		users.fbid,
		COALESCE(users.oauth_token, u2.oauth_token) oauth_token,
		UNIX_TIMESTAMP(users.date_updated) uts_updated,
		users.date_joined
	FROM users
	LEFT JOIN friends
	ON users.fbid = friends.friend_fbid
	LEFT JOIN users u2
	ON friends.user_fbid = u2.fbid
	WHERE COALESCE(users.oauth_token, u2.oauth_token) IS NOT NULL
	AND (users.fbid = ? OR FLOOR(?) = 0)
	ORDER BY users.date_updated, users.update_priority, users.name
	LIMIT 3
', $ufbid, $ufbid);
$affectedRows = 0;

header('Content-Type: text/plain');
foreach ($users as $u) {
	try {
		// Check if there's a OAuth token for the user
		if (!$u['oauth_token']) continue;

		// Limit maximum execution time to 60 seconds per user
		set_time_limit(60);

		// Set access token to the one retrieved from DB
		$fb->setAccessToken($u['oauth_token']);
		
		if ($u['date_joined']) {
			// Update friends
			$posts = $fb->api("/$u[fbid]/posts?limit=10");
			$priorities[] = array();
			foreach ($posts['data'] as $p) {
				if (isset($p['story_tags'])) {
					foreach ($p['story_tags'] as $t) {
						$priorities[$t[0]['id']] = isset($priorities[$t[0]['id']]) ? max(2, $priorities[$t[0]['id']] - 1) : 8;
					}
				}
			}

			$ps = $db->prepare('INSERT IGNORE INTO friends(user_fbid, friend_fbid) VALUES(?, ?)');
			$ups = $db->prepare('INSERT IGNORE INTO users(fbid, name, update_priority) VALUES(?, ?, ?)');
			$friends = $fb->api("/$u[fbid]/friends");
			foreach ($friends['data'] as $f) {
				$ps->execute(array($u['fbid'], $f['id']));
				$ups->execute(array($f['id'], $f['name'], isset($priorities[$f['id']]) ? $priorities[$f['id']] : 9));
			}
		}

		// Update posts
		$stmt = $db->prepare("INSERT IGNORE INTO posts(fbid, content, user_fbid, dt) VALUES(?, ?, ?, ?)");
		$posts = $fb->api("/$u[fbid]/posts?since=$u[uts_updated]&limit=5000");
		foreach ($posts['data'] as $p) {
			if (!empty($p['message'])) $stmt->execute(array($p['id'], $p['message'], $u['fbid'], $p['created_time']));
		}

		// Update likes
		$stmt = $db->prepare("INSERT IGNORE INTO likes(user_fbid, object_fbid, category, title, dt) VALUES(?, ?, ?, ?, ?)");
		$likes = $fb->api("/$u[fbid]/likes?since=$u[uts_updated]&offset=0&limit=5000");
		foreach ($likes['data'] as $l) {
			$stmt->execute(array($u['fbid'], $l['id'], $l['category'], $l['name'], $l['created_time']));
		}
		
		
		// FB API tends to return "An unknown error has occurred" when pulling a friend's checkins,
		// hence we're making it optional by putting it in its own try-catch
		try {
			// Update checkins
			$ps = $db->prepare('INSERT IGNORE INTO checkins(fbid, title, lat, lng, dt) VALUES(?, ?, ?, ?, ?)');
			$checkins = $fb->api("/$u[fbid]/checkins?since=$u[uts_updated]&limit=5000");
			foreach ($checkins['data'] as $c) {
				$ps->execute(array($u['fbid'], $c['place']['name'], $c['place']['location']['latitude'], $c['place']['location']['longitude'], $c['created_time']));
			}
		} catch (Exception $e) {
			appLog($e);
		}

		// Update date_updated to current time
		$affectedRows += $db->q('UPDATE users SET date_updated = NOW() WHERE fbid = ?', $u['fbid']);
	} catch (Exception $e) {
		$db->q('UPDATE users SET date_updated = date_updated + INTERVAL 1 SECOND WHERE fbid = ?', $u['fbid']); // Increment last_updated by 1 second so that it moves behind in the update queue
		appLog($e);
	}
}
$interval = microtime(true) - $startTime;
echo "Updated $affectedRows users in $interval seconds.";

?>